/**
 * 给流程添加各种规则验证，by  zili   2015-05-19
 */
var  allParams = {"firstId":"","startPathNum":0};
function save(data) {
	    allParams.firstId = "";
	    allParams.startPathNum = 0;
		var obj = eval('('+data+')');
		var flowName = obj.props.props.name.value;
		var result = validateFlow(obj);
		var flag = true;
		//false证明是验证通过的
		for(pro in result){
			if(result[pro]){
				flag = false;
				break;
			}
		 }
		if(flag){
			data = data.replace(new RegExp("'","gm"),function(){var un;return '^';})
			data = encodeURIComponent(data);
			data = data.replace(new RegExp("%","gm"),function(){return '~';});
			var request = $.ajax({
				url : getXCtxPath()+"/jbpmService/defineFlow/deploy",
				async:false,
				type : "POST",
				data : {
					flow : data,
					detailId :detailId,
					flowName : flowName
				}
			});
			request.done(function(msg) {
				var data = msg.split(";");
				detailId = data[0];
				dialog.alert(data[1]);
			});
		}else{
			for(pro in result){
				if(result[pro]){
					dialog.alert(result[pro]);
					break;
				}
			}
		}
	}
//--验证path
    function validatePath(obj){
    	 var res = "";
    	 var nodes = {};
    	 var decision = {"leftNum":1,"rightNum":2,"leftOp":"=","rightOp":">=","leftIds":[],"rightIds":[],"leftInfo":"从'决定'节点的进入连线只能有一条！","rightInfo":"从'决定'节点出来的连线必须大于等于两条！"};
    	 var fork = {"leftNum":1,"rightNum":2,"leftOp":"=","rightOp":">=","leftIds":[],"rightIds":[],"leftInfo":"从'分支'节点的进入连线只能有一条！","rightInfo":"从'分支'节点出来的连线必须大于等于两条！"};
    	 var join = {"leftNum":2,"rightNum":1,"leftOp":">=","rightOp":"=","leftIds":[],"rightIds":[],"leftInfo":"从'合并'节点的进入连线必须大于等于两条！","rightInfo":"从'合并'节点出来的连线只能有一条！"};
    	 var dfork = {"leftNum":1,"rightNum":1,"leftOp":"=","rightOp":"=","leftIds":[],"rightIds":[],"leftInfo":"从'动态分支'节点的进入连线只能有一条！","rightInfo":"从'动态分支'节点出来的连线只能有一条！"};
    	 var djoin = {"leftNum":1,"rightNum":1,"leftOp":"=","rightOp":"=","leftIds":[],"rightIds":[],"leftInfo":"从'动态合并'节点的进入连线只能有一条！","rightInfo":"从'动态合并'节点出来的连线只能有一条！"};
    	 if(isNullObj(obj["paths"])){
    	 	res = "节点之间应该有连线！";
    	 }else{
    	 	for(p in obj["paths"]){
    	 		var path = obj["paths"][p];
			    var from = obj["states"][path.from];
			    var to = obj["states"][path.to];
			    nodes[path.from] = from;
			    nodes[path.to] = to;
    	 		if(from.type=="decision"){//从决定节点右出
    	 			decision["rightIds"].push(path.from);
    	 		}else if(from.type=="fork"){//从分支节点右出
    	 			fork["rightIds"].push(path.from);
    	 		}else if(from.type=="join"){//从合并节点右出
    	 			join["rightIds"].push(path.from);
    	 		}else if(from.type=="foreach"){//从动态分支节点右出
    	 			dfork["rightIds"].push(path.from);
    	 		}else if(from.type=="loopjoin"){//从动态合并节点右出
    	 			djoin["rightIds"].push(path.from);
    	 		}
    	 		
    	 		if(to.type=="decision"){//从决定节点左进
    	 			decision["leftIds"].push(path.to);
    	 		}else if(to.type=="fork"){//从分支节点左进
    	 			fork["leftIds"].push(path.to);
    	 		}else if(to.type=="join"){//从合并节点左进
    	 			join["leftIds"].push(path.to);
    	 		}else if(to.type=="foreach"){//从动态分支节点左进
    	 			dfork["leftIds"].push(path.to);
    	 		}else if(to.type=="loopjoin"){//从动态合并节点左进
    	 			djoin["leftIds"].push(path.to);
    	 		}
    	 	}
    	 	//--判断path对应的节点和obj里存放的节点是否相等
    	 	var pathToNode = 0;
    	 	var objToNode = 0;
    	 	for(pro in nodes){
    	 		pathToNode++;
    	 	}
    	 	for(pro in obj["states"]){
    	 		objToNode++;
    	 	}
    	 	if(pathToNode<objToNode){
    	 		res = "所有节点之间必须有连线！";
    	 		return res;
    	 	}
    	 	//--判断其他路径
    	 	res = validatePathNum(decision);
    	 	if(res){
    	 		return res;
    	 	}
    	 	res = validatePathNum(fork);
    	 	if(res){
    	 		return res;
    	 	}
    	 	res = validatePathNum(join);
    	 	if(res){
    	 		return res;
    	 	}
    	 	res = validatePathNum(dfork);
    	 	if(res){
    	 		return res;
    	 	}
    	 	res = validatePathNum(djoin);
    	 	if(res){
    	 		return res;
    	 	}
    	 }
    	 return res;
    }
    //--判断路径条数是否正确
    function validatePathNum(obj){
    	var result = "";
    	if(obj.leftIds.length==0&&obj.rightIds.length==0){
    		return result;
    	}
    	var left_res = {};
    	var right_res = {};
       for(i=0;i<obj.leftIds.length;i++){
		  if(left_res[obj.leftIds[i]]){
		    left_res[obj.leftIds[i]]+=1;
		  }else{
		    left_res[obj.leftIds[i]] = 1;
		  }
        }
       //--验证从左侧进来的连线条数
        for(o in left_res){
        	if(obj.leftOp=="="){
        		if(left_res[o]!=obj.leftNum){
        			result = obj.leftInfo;
        			return result;
        		}
        	}else{
        		if(left_res[o]<obj.leftNum){
        			result = obj.leftInfo;
        			return result;
        		}
        	}
        }
        for(j=0;j<obj.rightIds.length;j++){
		  if(right_res[obj.rightIds[j]]){
		    right_res[obj.rightIds[j]]+=1;
		  }else{
		    right_res[obj.rightIds[j]] = 1;
		  }
        }
         //--验证从右侧进来的连线条数
         for(o in right_res){
        	if(obj.rightOp=="="){
        		if(right_res[o]!=obj.rightNum){
        			result = obj.rightInfo;
        			return result;
        		}
        	}else{
        		if(right_res[o]<obj.rightNum){
        			result = obj.rightInfo;
        			return result;
        		}
        	}
        }
         return result;
    }
    //--验证回退
    function validateBack(obj){
    	var res = "";
    	if(isNullObj(obj["paths"])){
    	 	return res;
    	 }
    	var backs = ["start","fork","join","decision","foreach","loopjoin"];
    	var errorInfo = {"start":"回退到某个节点不能是'开始'节点！","fork":"回退到某个节点不能是'分支'节点！","join":"回退到某个节点不能是'合并'节点！"
    	,"decision":"回退到某个节点不能是'决定'节点！","foreach":"回退到某个节点不能是'动态分支'节点！"
    	,"loopjoin":"回退到某个节点不能是'动态合并'节点！","other":"回退到某个节点不能是'任务多出口'中的任务节点！"};
    	for(pro in obj["paths"]){
    		 var toStr = obj["paths"][pro].to;
    	     var to = obj["states"][toStr];
    	     var fromStr = obj["paths"][pro].from;
    	     var from = obj["states"][fromStr];
    		
    		//--退回上一步不能是backs中的任一节点
	     	if(validateStrInArray(from.type,backs)){
	     		if(to.props.temp2){
	     		  to.props.temp2.value=="0";//将退回上一步的值置“0”
	     		}
	     	}
    	}
    	for(pro in obj["states"]){
    		 var task = obj["states"][pro];
    		//--回退到某个节点不能是backs中的任一节点
    		if(task.text.text.substring(task.text.text.length-3).indexOf("_ht")>-1){
    	      if(validateStrInArray(task.type,backs)){
    	      	 res = errorInfo[task.type];
    	      }
    		}
    	}
    	return res;
    }
    //--判断串是否在数组中
    function validateStrInArray(str,array){
    	var flag = false;
    	for(var i=0;i<array.length;i++){
    		if(array[i]==str){
    			flag = true;
    			break;
    		}
    	}
    	return flag;
    }
    //--判断空对象
    function isNullObj(obj){
     for(var i in obj){
        if(obj.hasOwnProperty(i)){
            return false;
        }
     }
    return true;
}
//--验证流程名称
    function validateFlowName(flowName){
    	var res = "";
    	if(!flowName){
			res = "流程名称不能为空！";
		}else{
			$.ajax({
			    type : "POST",
			    async:false,
				url : getXCtxPath()+"/workflow/flow!checkFlowName.action",				
		 				data: "entity.flowName=" + flowName+"&id="+flow_id+"&detailId="+detailId,
				success : function(msg){
					var obj = eval('('+msg+')');
					if(obj==false){
						res = "流程名称已经存在！";
					}
				}
	        });
		}
		return res;
    }
    function validateFlow(obj){
    	var _result = {"flowName":false,"taskName":false,"start":false,"end":false,"path":false,"task":false,"joinFork":false,"djoinFork":false
    	,"back":false};
    	var flowName = obj.props.props.name.value;
    	/*state--任务名称是否可用;rects--存放 任务 名字的数组;forks--分支  数量;joins--合并  数量
    	start--开始的个数;end--结束的个数;dforks--动态分支数量;djoins--动态合并数量*/
    	var params = {"state":true,"rects":{},"forks":0,"joins":0,"start":0,"end":0,"dforks":0,"djoins":0};
		_result.flowName = validateFlowName(flowName);
		if(_result.flowName){
			return _result;
		}
		for(pro in obj){
			if(pro == "states"){
				var i=1;
				for(values in obj[pro]){
					 if(obj[pro][values].type == 'start'){
					 	params.start++;
					 }else if(obj[pro][values].type == 'end'){
					 	params.end++;
					 }
					 else if(obj[pro][values].type == 'task'){
						if(i==1){
							params.rects[i-1] = obj[pro][values].text.text;
						}else{
							params.state = checkSave(params.rects,obj[pro][values].text.text);
							if(params.state == true){
								params.rects[i-1] = obj[pro][values].text.text;
							}else{
								_result.taskName = "任务名称有重复！";
								break;
							}
						}
						i++;	
						}else if(obj[pro][values].type == 'fork'){
							i++;
							params.forks = params.forks+1;
						}else if(obj[pro][values].type == 'join'){
							i++;
							params.joins = params.joins+1;
						}else if(obj[pro][values].type == 'foreach'){
							i++;
							params.dforks = params.dforks+1;
						}else if(obj[pro][values].type == 'loopjoin'){
							i++;
							params.djoins = params.djoins+1;
						}
						else{
							i++;
						}
					}
			}
		}
		 //判断 分支 合并 数量是否相等
		if(params.forks != params.joins){
			_result.joinFork = "分支与合并必须成对存在！";
			return _result;
		}
		//判断动态分支合并数量是否相等
		if(params.dforks!=params.djoins){
			_result.djoinFork = "动态分支与动态合并必须成对存在!";
			return _result;
		}
		//判断开始节点的个数
		if(params.start==0){
			_result.start = "必须有开始节点！";
			return _result;
		}else if(params.start>1){
			_result.start = "开始节点只能有一个！";
			return _result;
		}
		//判断结束节点的个数
		if(params.end==0){
			_result.end = "必须有结束节点！";
			return _result;
		}else if(params.end>1){
			_result.end = "结束节点只能有一个！";
			return _result;
		}
		_result.back = validateBack(obj);//--验证回退
		if(_result.back){
			return _result;
		}
		_result.path = validatePath(obj);//--验证路径
		if(_result.path){
			return _result;
		}
		for(p in obj["paths"]){
			var path = obj["paths"][p];
			_result.task = validateTask(path,obj);//--验证task
			if(_result.task){
				return _result;
			}
		}
		if(allParams.startPathNum>1){
			_result.start = "起草节点只能有一个!";
		}
		return _result;
    }
    //--验证起草节点不能退回且不能设置分支条件的规则并直接置值，再验证其他task必须设置执行人
    function validateTask(path,obj){
      var res = "";
	  var from = obj["states"][path.from];
	  var to = obj["states"][path.to];
	  if(from.type == "start"){//开始节点
	  	 allParams.startPathNum++;
		if(to.type!="task"){
			res = "起草节点必须是'任务'节点!";
			return  res;
		}else{
			//起草节点不能有退回
		   to.props.temp2.value="0";
		   to.props.temp3.value="0";
		   //不能设置分支条件
		   to.props.condition.value = "";
		   //不能设置执行人
		   to.props.assignee.value = "";
		   allParams.firstId = path.to;
		}
	  }else{
	  	 if(from.type=="task"&&allParams.firstId!=path.from){
	  	 	 if(!from.props.assignee.value){
	  	 	 	res = "除了起草'任务'，其他任务必须设置'执行人'！";
	  	 	 	return  res;
	  	 	 }
	  	 }
	  	 if(to.type=="task"&&allParams.firstId!=path.to){
	  	 	if(!to.props.assignee.value){
	  	 	 	res = "除了起草'任务'，其他任务必须设置'执行人'！";
	  	 	 	return  res;
	  	 	 }
	  	 }
	  	 if(from.type=="decision"){
	  	 	if(to.type=="task"&&!to.props.condition.value){
	  	 		res = "从'决定'节点出来的任务必须设置'分支条件'!";
	  	 		return  res;
	  	 	}
	  	 }
	  	 if(from.type=="fork"){
	  	 	if(to.type!="task"){
	  	 		res = "从'分支'节点出来的节点必须是'任务'！";
	  	 	}
	  	 }
	  	 if(from.type=="foreach"){
	  	 	if(to.type!="task"){
	  	 		res = "从'动态分支'节点出来的节点必须是'任务'！";
	  	 	}
	  	 }
	  	 if(to.type=="decision"){
	  	 	if(from.type!="task"){
	  	 		res = "从'决定'节点进入的节点必须是'任务'！";
	  	 	}
	  	 }
	  	if(to.type=="fork"){
	  	 	if(from.type!="task"){
	  	 		res = "从'分支'节点进入的节点必须是'任务'！";
	  	 	}
	  	 }
	  	if(to.type=="join"){
	  	 	if(from.type!="task"){
	  	 		res = "从'合并'节点进入的节点必须是'任务'！";
	  	 	}
	  	 }
	  	if(to.type=="foreach"){
	  	 	if(from.type!="task"){
	  	 		res = "从'动态分支'节点进入的节点必须是'任务'！";
	  	 	}
	  	 }
	  	if(to.type=="loopjoin"){
	  	 	if(from.type!="task"){
	  	 		res = "从'动态合并'节点进入的节点必须是'任务'！";
	  	 	}
	  	 }
	  }
	  return res;
    }
	/*判断数组中是否包含此字符*/
	function checkSave(arrays,string){
		var state = true;
		for(num in arrays){
			if(arrays[num] == string){
				state = false;
				return false;
			}
		}
		if(state){
			return true;
		}
	}
	
	function showXml(data) {
		data = encodeURIComponent(data);
		data = data.replace(new RegExp("%","gm"),function(){return '~';});
		var request = $.ajax({
			url : getXCtxPath()+"/jbpmService/defineFlow/showXml",
			type : "POST",
			data : {
				flow : data,
				detailId :detailId
			}
		});
		request.done(function(msg) {
			var msg1 = msg.replace(/\&/g,"&amp;").replace(/\</g,"&lt;");
			
			dialog.formModal("content:"+msg1, "展示xml源码",true,false);
		});
	}
	
	function showJson(data) {
		dialog.formModal("content:"+data, "展示JSON源码",true,false);
	}
	
	function copyFlowDetail(){
		if(detailId){
		    var href = getXCtxPath()+'/workflow/flow!toCopy.action?detailId='+detailId;
		    
			var obj = dialog.formModal(href, "另存为",true,false,510);
			dialog.bindAction($(obj).attr("id"),function(){
				var request = $.ajax({
					url : getXCtxPath()+"/workflow/flow!copyFlow.action",
					type : "POST",
					data :$("#flow-copy-form").serialize()
				});
				request.done(function(msg) {
					msg = util.strToObj(msg);
					dialog.alert(msg.desc);
					obj.modal('hide');
				});
			});
		}else{
			dialog.alert("请先保存再复制！");
		}
	}
	function getXCtxPath(){
		var contextPath = document.location.pathname; 
	    var index =contextPath.substr(1).indexOf("/"); 
	    contextPath = contextPath.substr(0,index+1);
	    return contextPath;
	}
